package com.example.wac.util;

import com.example.wac.entity.WeChatMessageResponse.*;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author wuancheng
 * @description
 * @date 2022-07-27 14:33:00
 */
public class WeChatMessageXMLUtil {
    /**
     * 解析xml请求
     *
     * @param request
     * @return
     * @throws Exception
     */
    public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        Map<String, String> map = new HashMap<>(8);
        // 取出输入流,使用dom4J获取文档对象
        try(InputStream inputStream = request.getInputStream();){
            SAXReader reader = new SAXReader();
            Document document = reader.read(inputStream);
            Element rootElement = document.getRootElement();
            // 获取根元素的所有节点
            List<Element> elements = rootElement.elements();
            // 遍历节点,将数据存入map
            for (Element e: elements) {
                map.put(e.getName(), e.getText());
            }

        }
        return map;
    }


    /**
     * 扩展xstream,支持CDATA
     */
    private static XStream xStream = new XStream(new XppDriver() {
        @Override
        public HierarchicalStreamWriter createWriter(Writer out) {
            return new PrettyPrintWriter(out) {
                boolean cdate = true;

                @Override
                public void startNode(String name, Class clazz) {
                    super.startNode(name, clazz);
                }

                @Override
                protected void writeText(QuickWriter writer, String text) {
                    if (cdate) {
                        writer.write("<![CDATA[");
                        writer.write(text);
                        writer.write("]]>");
                    }else {
                        writer.write(text);
                    }
                }
            };
        }
    });


    /**
     * 文本消息转换成xml
     *
     * @param textMessageResponse
     * @return
     */
    public static String messageToXml(TextMessageResponse textMessageResponse) {
        xStream.alias("xml", textMessageResponse.getClass());
        return xStream.toXML(textMessageResponse);
    }

    /**
     * 图片消息对象转换xml
     *
     * @param imageMessageResponse
     * @return
     */
    public static String messageToXml(ImageMessageResponse imageMessageResponse) {
        xStream.alias("xml", imageMessageResponse.getClass());
        return xStream.toXML(imageMessageResponse);
    }

    /**
     * 语音消息转换为xml
     *
     * @param voiceMessageResponse
     * @return
     */
    public static String messageToXml(VoiceMessageResponse voiceMessageResponse) {
        xStream.alias("xml", voiceMessageResponse.getClass());
        return xStream.toXML(voiceMessageResponse);
    }

    /**
     * 视频消息转换成xml
     *
     * @param videoMessageResponse
     * @return
     */
    public static String messageToXml(VideoMessageResponse videoMessageResponse) {
        xStream.alias("xml", videoMessageResponse.getClass());
        return xStream.toXML(videoMessageResponse);
    }

    /**
     * 音乐消息转换xml
     *
     * @param musicMessageResponse
     * @return
     */
    public static String messageToXml(MusicMessageResponse musicMessageResponse) {
        xStream.alias("xml", musicMessageResponse.getClass());
        return xStream.toXML(musicMessageResponse);
    }

    /**
     * 图文消息转换成xml
     *
     * @param articleMessageResponse
     * @return
     */
    public static String messageToXml(ArticleMessageResponse articleMessageResponse) {
        xStream.alias("xml", articleMessageResponse.getClass());
//        xStream.alias("item", new Article().getClass());
        return xStream.toXML(articleMessageResponse);
    }
}
